package gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

import Inputs.ImageLoader;
import algorithm.Mask;
import algorithm.TextureChanger;

public class FrameLoco extends javax.swing.JFrame implements Observer {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	{
		//Set Look & Feel
		try {
			javax.swing.UIManager.setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
		} catch(Exception e) {
			e.printStackTrace();
		}
	}

	private JPanel jPanel1;
	private JButton jButtonTakePicture;
	private JButton jButtonEnd;
	private JButton jButtonDeffect;
	public static JImagePanel imagePanelMask;
	private JButton jButtonOpenPicture;
	private DisplayCanvas imagePanel;
	private ImageLoader ia;
	private TextureChanger fc;
	private ColorPalette cp;
	private JPanel palette;

	/**
	* Auto-generated main method to display this JFrame
	*/
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				FrameLoco inst = new FrameLoco();
				inst.setLocationRelativeTo(null);
				inst.setVisible(true);
			}
		});
	}
	
	public FrameLoco() {
		super();
		initGUI();
	}
	
	public ImageIcon createImageIcon(String path) {
		java.net.URL imageURL = this.getClass().getResource(path);

		if (imageURL == null) {
			System.err.println("Resource not found: " + path);
			return null;
		} else {
			return new ImageIcon(imageURL);
		}
	}
	
	private void initGUI() {
		try {
			ia = new ImageLoader();
			setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
			{
				
				
				jPanel1 = new JPanel();
				getContentPane().add(jPanel1, BorderLayout.CENTER);
				jPanel1.setLayout(null);
				initPalette();

				{
					imagePanel = new DisplayCanvas();
					jPanel1.add(imagePanel);
					imagePanel.setAutoscrolls(true);

					{
						jButtonOpenPicture = new JButton();
						jPanel1.add(jButtonOpenPicture);
						jButtonOpenPicture.setText("Abrir foto");
						jButtonOpenPicture.setBounds(800, 384, 112, 21);
						jButtonOpenPicture.addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent evt) {
								jButtonOpenPictureActionPerformed(evt);
							}
						});
					}
					{
						jButtonTakePicture = new JButton();
						jPanel1.add(jButtonTakePicture);
						jButtonTakePicture.setText("Tomar Foto");
						jButtonTakePicture.setBounds(800, 416, 112, 21);
						jButtonTakePicture.addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent evt) {
								jButtonTakePictureActionPerformed(evt);
							}
						});
					}
					{
						jButtonDeffect = new JButton();
						jButtonDeffect.setEnabled(false);
						jPanel1.add(jButtonDeffect);
						jButtonDeffect.setText("Por Defecto");
						jButtonDeffect.setBounds(800, 327, 122, 21);
						jButtonDeffect.addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent evt) {
								jButtonDeffectActionPerformed(evt);
							}
						});
					}
					{
						jButtonEnd = new JButton();
						jPanel1.add(jButtonEnd);
						jButtonEnd.setText("Finalizar");
						jButtonEnd.setBounds(800, 446, 122, 21);
						jButtonEnd.addActionListener(new ActionListener() {
							public void actionPerformed(ActionEvent evt) {
								jButtonEndActionPerformed(evt);
							}
						});
					}
				}
			}
			
			ArrayList<Mask> masks = new ArrayList<Mask>();
			for (int i = 0; i < 6; i++) {
				Mask mask = new Mask(loadMask("/Imagenes/Remera"+(i+1)+".png"));
				masks.add(mask);
			}
			fc = new TextureChanger(imagePanel.getImageAux(),masks);
			
			pack();
			this.setExtendedState(JFrame.MAXIMIZED_BOTH);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private BufferedImage loadMask(String path){
		Image image = createImageIcon(path).getImage();
		BufferedImage mask = new BufferedImage(image.getWidth(this), image.getHeight(this),
	        BufferedImage.TYPE_INT_ARGB);
		Graphics2D g = mask.createGraphics();
		g.drawImage(image, 0, 0, null); 
	    g.dispose(); 
	    
	    return mask;
	}
	
	private void initPalette() {

		cp = new ColorPalette(this);
		palette = cp.getPalette();
		palette.setLocation(800, 500);
		jPanel1.add(palette);
		}

	private void jButtonOpenPictureActionPerformed(ActionEvent evt) {
		ia.loadAndDisplayImage(imagePanel, this);
		imagePanel.setBounds(61, 24, 512, 512);
		jButtonDeffect.setEnabled(true);

	}
	
	
	private void jButtonDeffectActionPerformed(ActionEvent evt) {
		imagePanel.reset();
		imagePanel.setimageOnly(imagePanel.getImageAux());
		imagePanel.repaint();
	}
	
	private void jButtonTakePictureActionPerformed(ActionEvent evt) {
		System.out.println("jButtonTakePicture.actionPerformed, event="+evt);
	}
	
	private void jButtonEndActionPerformed(ActionEvent evt) {
		fc.setDisplay(imagePanel.getImageAux());
		
		JDialog d = new JDialog();
		JImagePanel im = new JImagePanel();

		fc.setMascara(cp.getCurrent());
		BufferedImage b = fc.getTextureChanged();
		im.setimage(b);
		im.setBounds(0, 0, 600, 600);
		d.setSize(158, 255);
		d.add(im);
		d.setVisible(true);
		try {
			ImageIO.write(b, "png", new File("C:/Users/Administrador/Desktop/cara.png"));
		} catch (IOException e) {
			e.printStackTrace();
		}
		
	}
	
	public void changeTexture(){
		
		SwingUtilities.invokeLater(new Runnable() {
			
			@Override
			public void run() {
				imagePanel.setimageOnly(fc.getTextureChanged());
				imagePanel.repaint();
				
				
			}
		});
	
	}


	public void applyTexture() {
		fc.setMascara(cp.getCurrent());
		fc.setDisplay(imagePanel.getImageAux());

		changeTexture();

	}

	@Override
	public void update(Observable obs, Object arg1) {
		if (obs == cp){
			
			applyTexture();
			
		}
	}

}
